package org.daochong.web.filter;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SecurityParameterUtils {
	public static Map<String, Pattern> REG_LIST = new HashMap<String, Pattern>();
	public static String sqlKeywords = "insert|update|delete|select|from|where|group|order|and|or|set|exec|execute";
	public static String sqlFunctions = "exists|count|substr|max|min|avg|left|mid";

	static {
		REG_LIST.put("包含chr()", Pattern.compile("(.*[^a-zA-Z_0-9]{1}chr|chr)\\s*\\(\\s*\\d.\\s*\\).*"));
		REG_LIST.put("sqlKeywords", Pattern
				.compile("(.*[^a-zA-Z_0-9]{1}(" + sqlKeywords + ")|(" + sqlKeywords + ")){1}[^a-zA-Z_0-9]{1}.*"));
		REG_LIST.put("sqlFunctions",
				Pattern.compile("(.*[^a-zA-Z_0-9]{1}(" + sqlFunctions + ")|(" + sqlFunctions + ")){1}\\s*\\(.*\\).*"));
	}

	public static void check(String val, String charSet) throws SecurityException {
		try {
			if (charSet != null)
				val = URLDecoder.decode(val, charSet);
			else
				val = URLDecoder.decode(val, "ISO-8859-1");
		} catch (UnsupportedEncodingException e) {
			throw new SecurityException("charset " + charSet + " not support");
		}
		int c;
		for (int i = 0; i < val.length(); i++) {
			c = val.charAt(i);
			if ((c == 127) || ((c < 32) && (c != 10) && (c != 13))) {
				throw new SecurityException("Spec Chars");
			}
		}
		if (val.indexOf("<?xml ") >= 0) {
			throw new SecurityException("Not Support XML");
		}
		for (String key : REG_LIST.keySet()) {
			Pattern p = (Pattern) REG_LIST.get(key);
			Matcher m = p.matcher(val);
			if (m.matches()) {
				String title = m.group(m.groupCount() - 1);
				throw new SecurityException(key + ":" + title);
			}
		}
	}

	public static String filter(String val) {
		if (val == null)
			return val;
		return val.replaceAll("'", "''").replaceAll(">", "&gt;").replaceAll("<", "&lt;").replaceAll("\"", "&quot;");
	}

	public static Map<String, String[]> parseQueryString(String s) {
		String valArray[] = null;
		if (s == null) {
			throw new IllegalArgumentException();
		}
		Map<String, String[]> ht = new HashMap<String, String[]>();
		StringTokenizer st = new StringTokenizer(s, "&");
		while (st.hasMoreTokens()) {
			String pair = (String) st.nextToken();
			int pos = pair.indexOf('=');
			if (pos == -1) {
				continue;
			}
			String key = pair.substring(0, pos);
			String val = pair.substring(pos + 1, pair.length());
			if (ht.containsKey(key)) {
				String oldVals[] = (String[]) ht.get(key);
				valArray = new String[oldVals.length + 1];
				for (int i = 0; i < oldVals.length; i++) {
					valArray[i] = oldVals[i];
				}
				valArray[oldVals.length] = val;
			} else {
				valArray = new String[1];
				valArray[0] = val;
			}
			ht.put(key, valArray);
		}
		return ht;
	}

	public static String processQueryString(String s) {
		if (s == null) {
			throw new IllegalArgumentException();
		}
		String re = "";
		StringTokenizer st = new StringTokenizer(s, "&");
		while (st.hasMoreTokens()) {
			String pair = (String) st.nextToken();
			int pos = pair.indexOf('=');
			if (pos == -1) {
				continue;
			}
			String key = pair.substring(0, pos);
			String val = pair.substring(pos + 1, pair.length());
			key = filter(key);
			val = filter(val);
			re += "&" + key + "=" + val;
		}
		if (re.length() > 1) {
			re = re.substring(1);
		}
		return re;
	}
}